<template>
  <div class="index-wrapper">
    <!-- 三栏水平排布 -->
    <div class="index-row">
      <div class="index-left">
        <div class="left-top">
          <MediaDevice :switchAudioDevice="switchAudioDevice" :switchVideoDevice="switchVideoDevice"/>
        </div>
        <div class="left-bottom">
          <Log/>
        </div>
      </div>
      <div class="index-center">
        <div class="local-window" ref="localWindowDiv">
          <LocalWindow ref="localWindow"/>
        </div>
        <div class="remote-window" v-if="singleCallSession != null" ref="remoteWindowDiv">
          <RemoteWindow ref="remoteWindow" :singleCallSession="singleCallSession" :exitSingleChat="exitSingleChat" :swapSingleChatWindow="swapSingleChatWindow"/>
        </div>
        <div class="local-window" v-if="participantFullScreen">
          <ParticipantFullWindow ref="participantFullWindow" :participantCancelFullScreen="participantCancelFullScreen"/>
        </div>
      </div>
      <div class="index-right">
        <template v-if="groupCallSession == null">
          <User v-if="menuSelected === 'single'" :callSingleChat="callSingleChat" :hangUpSingleChat="hangupSingleChat"
                :calling="calling" :confirmHangup="confirmHangup"/>
          <Room v-if="menuSelected === 'group'" :callGroupChat="callGroupChat" :user="user"
                :confirmHangup="confirmHangup"/>
        </template>
        <template v-else>
          <GroupChat ref="groupChat" :groupCallSession="groupCallSession" :participantCastFullScreen="participantCastFullScreen" :participantCancelFullScreen="participantCancelFullScreen"  :exitGroupChat="exitGroupChat" :user="user"/>
        </template>
      </div>
    </div>

    <!-- 底部导航 -->
    <div class="index-menu-bar">
      <MenuBar :menuSelected="menuSelected" :changeMenuSelected="changeMenuSelected"/>
    </div>


    <CallWaiting :calling="calling" :cancelCallRing="cancelCallRing" :receivedCallRingRespond="receivedCallRingRespond"
                 v-if="isCallingWait"/>

    <IncomingCalling ref="callRing" :singleCallRingRespond="singleCallRingRespond" :confirmHangup="confirmHangup"/>


    <div class="index-tools">
      <UserCard/>
      <ServiceLink/>
      <el-tooltip content="点击退出登录" placement="top">
        <div class="tool-logout-icon" @click="logout">
          <font-awesome-icon icon="fas fa-sign-out-alt"/>
        </div>
      </el-tooltip>
    </div>
  </div>
</template>

<script>
import MediaDevice from "@/components/left/MediaDevice.vue";
import LocalWindow from "@/components/center/LocalWindow.vue";
import User from "@/components/right/User.vue";
import Room from "@/components/right/Room.vue";
import GroupChat from '@/components/right/GroupChat.vue'
import ServiceLink from "@/components/bottom/ServiceLink.vue";
import MenuBar from "@/components/bottom/MenuBar.vue";
import Log from "@/components/left/Log.vue";
import {reqCallRing,} from "@/api/nats/private_chat";
import UserCard from "@/components/bottom/UserCard.vue";
import IncomingCalling from "@/components/bottom/IncomingCalling.vue";
import CallWaiting from "@/components/center/CallWaiting.vue";
import {getCache ,removeCache} from "@/utils/local_cache";
import RemoteWindow from "@/components/center/RemoteWindow.vue";
import ParticipantFullWindow from "@/components/center/ParticipantFullWindow.vue";
import {logout} from "@/api/http/user";

export default {
  name: "Index",
  components: {
    RemoteWindow,
    CallWaiting,
    IncomingCalling,
    UserCard,
    LocalWindow,
    ServiceLink,
    MediaDevice,
    User,
    Room,
    MenuBar,
    Log,
    GroupChat,
    ParticipantFullWindow
  },
  data() {
    return {
      localStream: {
        using: 'camera', // 默认使用摄像机的
        cameraStream: new MediaStream(),
        screenStream: new MediaStream()
      },
      menuSelected: 'single',
      user: null,
      calling: null,
      isCallingWait: false,
      singleCallSession: null,
      groupCallSession: null,
      participantFullScreen: false,
      callCommand: {
        call: 'call',
        agree: 'agree',
        reject: 'reject',
        cancel: 'cancel',
        hangup: 'hangup'
      },
      callType: {
        single: 'single',
        group: 'group'
      }
    }
  },
  provide() {
    return {
      localStream: this.localStream,
      callCommand: this.callCommand,
      callType: this.callType,
      publicKey: this.publicKey,
    }
  },
  methods: {
    logout() {
      this.cleanUp();
      logout();
      this.$router.push({name: 'Login'});
    },
    cleanUp() {
      this.stopMediaTracks(this.localStream.cameraStream);
      this.stopMediaTracks(this.localStream.screenStream);
      this.hangupGroupChat(this.calling?.callId);
      this.hangupSingleChat(this.calling?.callId);
      this.calling = null;
      removeCache('user');
    },

    hangupSingleChat(callId) {
      if (this.singleCallSession && this.singleCallSession.call.callId === callId) {
        this.singleCallSession = null;
        if (this.calling && this.calling.callId === callId) {
          this.calling = null
        }
      }
      this.resetSingleChatWindow();
    },

    hangupGroupChat(callId) {
      if (this.groupCallSession && this.groupCallSession.callId === callId) {
        this.$refs.groupChat.exitRoom();
        if (this.calling && this.calling.callId === callId) {
          this.calling = null
        }
        this.groupCallSession = null;
        this.resetGroupChatWindow();
      }
    },

    exitSingleChat() {
      let {callId} = this.singleCallSession.call;
      if (this.calling && this.calling.callId === callId) {
        this.calling = null;
      }
      this.resetSingleChatWindow();
      this.singleCallSession = null;
    },

    exitGroupChat() {
      let {callId} = this.groupCallSession;
      if (this.calling && this.calling.callId === callId) {
        this.calling = null;
      }
      this.resetGroupChatWindow();
      this.groupCallSession = null;
    },

    stopMediaTracks(stream) {
      if (stream && stream.getTracks) {
        stream.getTracks().forEach(track => track.stop());
      }
    },
    switchAudioDevice(deviceId) {
      this.$refs.localWindow.setCameraAudioStream(deviceId);
    },
    switchVideoDevice(deviceId) {
      this.$refs.localWindow.setCameraVideoStream(deviceId)
    },

    changeMenuSelected(menu) {
      this.menuSelected = menu
    },

    async callSingleChat(callee) {
      console.log(`呼叫用户 ${callee.nickname}`);

      // 同意已存在的呼叫
      if (this.agreeCallingRing(callee)) {
        return
      }

      try {
        const call = {
          type: this.callType.single,
          callId: this.$uuid(),
          callee,
          caller: this.user
        }

        const data = await reqCallRing({
          command: this.callCommand.call,
          call
        })

        if (data.code === 0) {
          // pop calling window
          this.calling = call
          this.isCallingWait = true;
        }

      } catch (err) {
        if (err.code === '503') {
          this.$message.error('对方无响应');
        }
      }

    },
    // 加入群聊
    callGroupChat(room, user) {
      this.calling = {
        type: this.callType.group,
        callId: room.roomCode,
        room: room,
        participant: user
      }
      this.groupCallSession = this.calling;
    },

    // 同意已存在的呼叫
    agreeCallingRing(callee) {
      let calls = this.$refs.callRing.calls;
      for (let i = 0; i < calls.length; i++) {
        if (calls[i].callee.id === callee.id) {
          this.$refs.callRing.handleCallRing(calls[i], this.callCommand.agree);
          return true;
        }
      }
      return false;
    },

    cancelCallRing() {
      this.calling = null
      this.isCallingWait = false
    },

    singleCallRingRespond(respond) {
      // 判断是否是同意,如果是同意则订阅webrtc协议
      if (respond.command === this.callCommand.agree) {
        this.calling = respond.call
        this.singleCallSession = {
          call: this.calling,
          isCaller: false
        }
      }
      return true;
    },

    receivedCallRingRespond(respond) {
      const {callee, callId} = respond.call;
      if (this.calling == null || this.calling.callId !== callId) {
        return
      }
      let command = respond.command;
      if (command === this.callCommand.reject) {
        this.$message.warning(`${callee.nickname}拒绝通话`)
        this.calling = null
      }
      if (command === this.callCommand.agree) {
        this.$message.success(`${callee.nickname}已同意,正在建立视频通话`)
        this.calling = respond.call;
        this.singleCallSession = {
          call: this.calling,
          isCaller: true
        }
      }
      this.isCallingWait = false
    },

    async confirmHangup() {
      if (this.calling) {
        return await this.$confirm('是否关闭当前通话?', '', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          if (this.calling.type === this.callType.single) {
            this.hangupSingleChat(this.calling.callId);
          } else {
            this.hangupGroupChat(this.calling.callId);
          }
          return true;
        }).catch(() => {
          return false;
        })
      }
      return true;
    },

    swapSingleChatWindow(){
       let localClass = this.$refs.localWindowDiv.className;
       this.$refs.localWindowDiv.className = this.$refs.remoteWindowDiv.className;
       this.$refs.remoteWindowDiv.className = localClass;
    },

    resetSingleChatWindow(){
      this.$refs.localWindowDiv.className = "local-window";
      if (this.$refs.remoteWindowDiv){
        this.$refs.remoteWindowDiv.className = "remote-window";
      }
    },
    participantCastFullScreen(participant){
      // 当前已经是有用户设置为全屏
      if (this.participantFullScreen){
        // 先把之前的全屏给取消掉
        this.$refs.groupChat.resetOtherParticipantFullScreen(participant.id);
      }
      const participantRef = this.$refs.groupChat.$refs[`participant_${participant.id}`][0];
      if (!participantRef){

        return
      }

      this.swapGroupChatWindow();
      this.participantFullScreen = true;
      this.$nextTick(()=>{
        this.$refs.participantFullWindow.setParticipant(participant);
        this.$refs.participantFullWindow.$refs.remoteVideo.srcObject = participantRef.$refs.remoteVideo.srcObject;
      });
    },
    participantCancelFullScreen(participantId){

      if (this.participantFullScreen && participantId){
        let participant = this.$refs.participantFullWindow.getParticipant();
        if (participant && participant.id !== participantId){
          return;
        }
      }
      this.resetGroupChatWindow();
      if(participantId){
        // 复位指定参加者的全屏
        this.$refs.groupChat.resetSpecifyParticipantFullScreen(participantId);
      }
    },
    swapGroupChatWindow(){
      this.$refs.localWindowDiv.className = 'remote-window'
    },
    resetGroupChatWindow(){
      this.participantFullScreen = false;
      this.$refs.localWindowDiv.className = 'local-window'
    }
  },
  mounted() {
    this.user = getCache('user');
  }
}
</script>


<style scoped>
/* 全局重置 */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* 整个页面容器：垂直布局（三栏一行 + 导航一条） */
.index-wrapper {
  width: 100%;
  height: 100vh;
  display: flex;
  flex-direction: column; /* 上下排列 */
  align-items: center; /* 整体水平居中 */
  gap: 20px; /* 三栏与导航条间距 */
  padding: 20px 0;
  background: linear-gradient(
      135deg,
      #0F1419 0%,
      #1A1F2E 60%,
      #2E1A29 80%,
      #2E1A29 100%
  );

}

/* 三栏容器 */
.index-row {
  display: flex;
  gap: 5px;
  height: 90%;
  width: 100%;
  padding: 0 20px; /* ← 把 20px 留给左右，而不是最外层 */
}

/* 比例 20% / 60% / 20% */
.index-left,
.index-right {
  flex: 0 0 20%;
}

.index-center {
  flex: 0 0 60%;
  overflow: hidden;
}

/* 其余毛玻璃、圆角样式不变 */

.index-center,
.index-right {
  background: rgba(255, 255, 255, 0.12);
  border-radius: 10px;
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.index-left {
  flex: 0 0 20%;
  display: flex;
  flex-direction: column;
  gap: 5px; /* 中间间隔为5px */
}

.left-top {
  flex-basis: 30%; /* 根据比例调整 */
  background: rgba(255, 255, 255, 0.12);
  border-radius: 10px;
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.left-bottom {
  flex-basis: 70%; /* 根据比例调整 */
  background: rgba(255, 255, 255, 0.12);
  border-radius: 10px;
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.index-center {
  border-radius: 15px;
}

/* 底部导航 */
.index-menu-bar {
  flex-shrink: 0;
  width: 320px;
  height: 60px;
  background: rgba(255, 255, 255, 0.15);
  border-radius: 30px;
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.25);
}

.index-tools {
  position: fixed;
  bottom: 20px;
  right: 20px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  height: 40px;
  background: rgba(194, 90, 90, 0.25);
  border-radius: 6px;
  backdrop-filter: blur(10px);
  border: 1px solid rgba(194, 90, 90, 0.4);
  z-index: 10;
}


.tool-logout-icon {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  color: #fff;
  transition: background-color 0.3s;
}

.tool-logout-icon:hover {
  background-color: rgba(255, 255, 255, 0.1);
}

@media (max-width: 1366px) {
  .index-row {
    height: 80vh; /* 降低主体高度 */
    gap: 8px; /* 减小栏间距 */
  }

  .index-left, .index-right {
    flex: 0 0 25.5%; /* 进一步调整侧边栏占比 */
  }

  .index-center {
    flex: 0 0 48%; /* 中间区域宽度适配 */
  }

  .left-top, .left-bottom {
    padding: 8px; /* 减小内边距 */
  }

  /* 调整右下角工具栏大小 */
  .index-tools {
    position: fixed;
    bottom: 20px;
    right: 20px;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    height: 40px;
    background: rgba(194, 90, 90, 0.25);
    border-radius: 6px;
    backdrop-filter: blur(10px);
    border: 1px solid rgba(194, 90, 90, 0.4);
    z-index: 10;
  }
}

.local-window{
  width: 100%;
  height: 100%;
}

.remote-window {
  height: 25%;
  width: 35%;
  bottom: 5px;
  right: 5px;
  overflow: hidden;
  border-radius: 15px;
  position: absolute;
  z-index: 99;
}


</style>